#include "IntrusiveListTest.h"
#include "CBL_IntrusiveList.h"
#include "CBL_SimpleIntrusiveList.h"

#include <iostream>

class CTestItem : public Cb::CIntrusiveList<CTestItem>::CItem
				, public Cb::CIntrusiveList<CTestItem,2>::CItem
{
public:
	
	CTestItem() : m_Value(1) {}
	CTestItem(int _Value) : m_Value(_Value) {}
	int m_Value;
};

// ------------------------------------------------------------------------------

BEGIN_TEST_CASE_IMPLEMENTATION(CIntrusiveListTest)
	
	typedef Cb::CIntrusiveList<CTestItem> CListType;
	CListType List;
	
	CTestItem Test1(1);
	CTestItem Test2(2);
	CTestItem Test3(3);
	
	// Basic add and iterator tests
	
	CHECK(List.IsEmpty(), "> empty test failed.");
	
	List.PushBack(Test1);
	
	CHECK(!List.IsEmpty(), "> not empty test failed.");
	CHECK(List.Size() == 1, "> size 1 test failed.");
	
	List.PushBack(Test2);
	List.PushFront(Test3);
	
	CHECK(List.Size() == 3, "> size 3 test failed.");
	
	CListType::CIterator TestIter = List.Begin();
	
	CHECK(TestIter->m_Value == 3, "> Begin() -> test failed.");
	CHECK((*TestIter).m_Value == 3, "> Begin() * test failed.");
	
	CListType::CIterator TestIter2 = TestIter++;
	
	CHECK(TestIter2->m_Value == 3, "> Iterator++ return test failed.");
	CHECK(TestIter->m_Value == 1, "> Iterator++ test failed.");
	
	++TestIter;
	
	CHECK(TestIter->m_Value == 2, "> ++Iterator test failed.");
	
	TestIter = List.Begin();
	int Count = 0;
	while (TestIter != List.End())
	{
		++Count;
		++TestIter;
	}
	
	CHECK(Count == 3, "> loop test failed.");
	
	List.Clear();
	
	CHECK(List.IsEmpty(), "> clear test failed.");
	
	CTestItem* pTest4 = new CTestItem(4);
	
	List.PushBack(*pTest4);
	
	delete pTest4;
	
	CHECK(List.IsEmpty(), "> delete item test failed.");
	
	// Different list swapping tests
	
	typedef Cb::CIntrusiveList<CTestItem, 2> CListType2;
	
	CListType List1;
	CListType2 List2;
	
	List.PushBack(Test1);
	List1.PushBack(Test1);
	List2.PushBack(Test2);
	
	CHECK(!List2.IsEmpty(), "> secondary list item test failed.");
	
	List2.Clear();
	
	CHECK(List.IsEmpty(), "> swap old clear test failed.");
	CHECK(!List1.IsEmpty(), "> swap new not clear test failed.");
	CHECK(List2.IsEmpty(), "> secondary list clear test failed.");
	
END_TEST_CASE_IMPLEMENTATION
